import * as echarts from 'echarts'
import type { EChartsOption, ECharts } from 'echarts'
import type { GeoJsonType } from '@/assets/types/MapTyps'
import chinaMapJson from '@/assets/china.json'
import { geoCoordMap } from '@/assets/utils/city'
import type { Children } from '@/assets/types/Disease'
import type { Ref } from 'vue'
import { reactive } from 'vue'
import type { TotalType } from '@/assets/types/Typs'

type pinDataType =
  | {
      name: string
      value: number[]
    }
  | undefined

//#region 初始地图配置
const defaultOption: EChartsOption = {
  geo: {
    id: 'geoMap',
    map: 'china',
    aspectScale: 0.75,
    // roam: true,
    layoutCenter: ['55%', '50%'],
    layoutSize: '100%',
    zoom: 1,
    scaleLimit: {
      //滚轮缩放的极限控制
      min: 1,
      max: 2,
    },
    itemStyle: {
      areaColor: {
        type: 'linear-gradient',
        x: 0,
        y: 1200,
        x2: 1000,
        y2: 0,
        colorStops: [
          {
            offset: 0,
            color: '#152E6E', // 0% 处的颜色
          },
          {
            offset: 1,
            color: '#0673AD', // 50% 处的颜色
          },
        ],
        global: true, // 缺省为 false
      },
      shadowColor: '#0f5d9d',
      shadowOffsetX: 0,
      shadowOffsetY: 15,
      opacity: 0.5,
    },
    // emphasis: {
    //   areaColor: '#0f5d9d',
    // },
  },
  series: [
    {
      id: 'seriesMap',
      type: 'map',
      map: 'china',
      roam: true,
      aspectScale: 0.75,
      layoutCenter: ['55%', '50%'], //地图位置
      layoutSize: '100%',
      zoom: 1, //当前视角的缩放比例
      // roam: false, //是否开启平游或缩放
      scaleLimit: {
        //滚轮缩放的极限控制
        min: 1,
        max: 2,
      },
      label: {
        show: true,
        color: '#000',
        fontSize: 10,
      },
      itemStyle: {
        // areaColor: '#0c3653',
        borderColor: '#1cccff',
        borderWidth: 1,
      },
      emphasis: {
        label: {
          show: true,
          color: '#fff',
        },
        itemStyle: {
          areaColor: '#1cccff',
        },
      },
      data: [],
      select: {
        disabled: true,
      },
    },
    {
      id: 'mapscatter',
      type: 'scatter',
      symbol: 'pin',
      coordinateSystem: 'geo',
      symbolSize: [35, 35],
      label: {
        fontSize: 12,
        show: true,
        formatter: (value: any) => {
          return value.data.value[2]
        },
      },
      itemStyle: {
        // color: '#FFCD00', //标志颜色
        // '#FF5370'//红
        // '#91cc75'//绿
        // '#FFCD00'//黄
        color: (value: any) => {
          if (value.data?.value[2] === 0) {
            return '#91cc75' //绿
          } else if (value.data?.value[2] > 0 && value.data?.value[2] < 10) {
            return '#FFCD00'
          } else {
            return '#FF5370'
          }
        },
      },
      data: [],
    },
  ],
}
//#endregion

const geoJsonCN = chinaMapJson

class MapEcharts {
  instance: ECharts | null = null
  private el: HTMLElement
  private geoJson = geoJsonCN
  originPinData = reactive(<Array<pinDataType>>[])
  pinData = reactive(<Array<pinDataType>>[])
  constructor(id: string | Ref<HTMLElement | undefined>, geo = geoJsonCN) {
    id === 'string'
      ? (this.el = document.getElementById(id)!)
      : (this.el = (id as Ref<HTMLElement>).value)
    echarts.dispose(this.el)
    this.initMap()
    this.geoJson = geo
    this.roam()
  }

  /***********************************************************************************
   * @description: 初始化地图
   * @return {*}
   ***********************************************************************************/
  initMap = (
    mapname: string = 'china',
    geo = JSON.stringify(geoJsonCN),
    options = defaultOption
  ) => {
    // 赋值

    echarts.registerMap(mapname, geo)
    this.instance
      ? this.instance.clear()
      : (this.instance = echarts.init(this.el))
    this.instance.setOption(options) // 传入初始配置
  }

  /***********************************************************************************
   * @description: 生成地图图钉数据
   * @param {Array} data 传入的是Children类型的数据
   * @return {*} pinData 返回的是[{name,value}...]
   ***********************************************************************************/
  updatePinData = (data: Array<Children>) => {
    // geo的坐标点，[x,y]添加nowconfirm =>   [x,y,nowConfirm]作为图标点的信息
    const pinData = data.map(item => {
      let nowConfirm = geoCoordMap[item.name] as Array<number>
      if (item.total.nowConfirm !== 0) {
        nowConfirm.push(item.total.nowConfirm)
        return { name: item.name, value: nowConfirm }
      }
    })
    // 清除this.pinData,重新赋值和更新实例配置项
    this.pinData.length = 0
    this.pinData.push(...pinData)
    this.instance!.setOption({
      series: [{ id: 'mapscatter', data: this.pinData }],
    })
  }
  /***********************************************************************************
   * @description 地图echart实例点击变更为该地区
   * @param itemsData reactive(<Array<TotalType>>[])
   * @param store 传入Pinia的store
   * @returns:void
   ***********************************************************************************/
  //  todo 获取点击点的省名与adcode
  //  todo 根据adcode获取GeoJson,改变region
  //  todo 根据GoJson更新地图
  //  todo 更新显示的数据
  clicktoChangemap(itemsData = reactive(<Array<TotalType>>[]), store: any) {
    this.instance!.on('click', e => {
      // console.log('点击事件：当前点击地区名字', e.name)
      if (store.region !== 'china') return
      let adcode: number = 0
      let province = ''

      this.geoJson.features.some(item => {
        if (item.properties.name === e.name) {
          adcode = item.properties.adcode as number
          // 处理省的名字，生成简略城市名
          switch (e.name) {
            case '内蒙古自治区':
              province = '内蒙古'
              break
            case '广西壮族自治区':
              province = '广西'
              break
            case '西藏自治区':
              province = '西藏'
              break
            case '宁夏回族自治区':
              province = '宁夏'
              break
            case '新疆维吾尔自治区':
              province = '新疆'
              break
            case '香港特别行政区':
              province = '香港'
              break
            case '澳门特别行政区':
              province = '澳门'
              break
            default:
              let arr = e.name.split('')
              arr.pop()
              province = arr.join('')
              break
          }
          store.isBack = true
          store.$state.region = province
        }
        return item.properties.name === e.name
      })
      // 改变相关展示数据
      itemsData.length = 0
      itemsData.push(...store.getitem!)
      new Promise(resolve => {
        resolve(store.getGeoJson(adcode))
      }).then(() => {
        this.updateMap(store.region, store.currentGeoJson)
        this.updateLocalPinData(store.$state.currentGeoJson, itemsData)
      })
    })
  }

  private updateLocalPinData(geo: GeoJsonType, data: Array<TotalType>) {
    // 生成省当地城市对应坐标
    const localGeoJson = geo.features.map(item => {
      let cityname: Array<string> | string = item.properties.name.split('')
      if (cityname[cityname.length - 1] === '市') {
        cityname.pop()
        cityname = cityname.join('')
      }
      return { name: cityname, value: item.properties.centroid }
    })
    let totaldata = data
    let container: {
      name: string
      value: number[]
    }
    //生成该省各城市包含的疫情数据
    const pinData = localGeoJson.map(item => {
      totaldata.some(dataitem => {
        if (item.name === dataitem.name) {
          let dataVal = item.value
          dataVal.push(dataitem.confirmAdd)
          container = { name: item.name, value: dataVal }
        }
        return item.name === dataitem.name
      })
      return container
    })
    //设置数据
    this.pinData.length = 0
    this.pinData.push(...pinData)
    this.instance!.setOption({
      series: [
        {
          id: 'mapscatter',
          data: this.pinData,
        },
      ],
    })
  }
  /***********************************************************************************
   * @description: 重绘为省地图
   * @param {any} store store实例
   * @param {any} province 省地区名
   * @param  adcode 省地区adcode
   *
   ***********************************************************************************/
  private async updateMap(region: string, geo: any) {
    let options = JSON.parse(JSON.stringify(defaultOption)) //序列化会忽略undefined、函数以及symbol 须重新赋值
    options.series[1].itemStyle = {
      color: (value: any) => {
        if (value.data?.value[2] === 0) {
          return '#91cc75' //绿
        } else if (value.data?.value[2] > 0 && value.data?.value[2] < 10) {
          return '#FFCD00'
        } else {
          return '#FF5370'
        }
      },
    }
    options.series[1].label.formatter = (value: any) => {
      return value.data.value[2]
    }
    ;(options.geo as echarts.MapSeriesOption).map = region
    ;(
      (options.series as echarts.SeriesOption[])[0] as echarts.MapSeriesOption
    ).map = region
    ;(options as EChartsOption).title = {
      text: '该省新增情况',
      left: '25%',
      textStyle: { color: '#fff' },
    }

    this.initMap(region, JSON.stringify(geo), options)
  }

  /*********************************************************************************** 
   * @description: 重置地图和相关数据
   * @param {any} store
   * @param {*} itemsData
   * @return {*}
   ***********************************************************************************/
  resetMap(store: any, itemsData = reactive(<Array<TotalType>>[])) {
    this.initMap('chian', store.originGeoJson)
    this.updatePinData(store.diseaseData.diseaseh5Shelf.areaTree[0].children)
    itemsData.length = 0
    itemsData.push(...store.getitem!)
  }

  /*********************************************************************************** 
   * @description: 同步拖拽和缩放时作为阴影的geomap的位置和缩放
   * @return {*}
   ***********************************************************************************/
  roam(){
    this.instance?.on('georoam',(e:any)=>{
      let center = (this.instance?.getOption()!as any).series[0].center
      let zoom = (this.instance?.getOption()!as any).series[0].zoom
      this.instance?.setOption({geo:{center:center,zoom:zoom}})   
    })
  }
}

export default MapEcharts
